package com.yenlien.traceyun.business.service;

import com.alibaba.fastjson.JSONArray;
import com.yenlien.traceyun.business.dao.TechnologyDao;
import com.yenlien.traceyun.business.entity.Technology;
import com.yenlien.traceyun.business.service.rest.usercenter.FileRestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.*;
import java.util.*;

/**
 * Created by LiuSha on 2020/6/11.
 */
@Service
public class TechnologyService {
    @Autowired
    private TechnologyDao technologyDao;
    @Autowired
    private FileRestService fileRestService;

    public Page<Technology> findByList(final Technology technology) {
        Pageable pageable = PageRequest.of(technology.getPage(), technology.getPageSize(), Sort.Direction.DESC, "createtime");
        return technologyDao.findAll(new Specification<Technology>() {
            private static final long serialVersionUID = 1L;

            @Override
            public Predicate toPredicate(Root<Technology> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Path<String> companyId = root.get("companyId");
                Path<String> pId = root.get("pId");
                //构造查询条件
                List<Predicate> andList = new ArrayList<>();
                List<Predicate> orList = new ArrayList<>();
                if (!StringUtils.isEmpty(technology.getCompanyId())) {
                    andList.add(cb.equal(companyId, technology.getCompanyId()));
                }
                Predicate[] predicate = new Predicate[andList.size()];
                Predicate Pre_And = cb.and(andList.toArray(predicate));
                orList.add(cb.isNull(pId));
                orList.add(cb.equal(pId, ""));
                Predicate[] arrayOr = new Predicate[orList.size()];
                Predicate Pre_Or = cb.or(orList.toArray(arrayOr));
                if (StringUtils.isEmpty(technology.getQuery())) {
                    return query.where(Pre_And, Pre_Or).getRestriction();
                }
                List<Predicate> or = new ArrayList<>();
                or.add(cb.like(root.get("name"), "%" + technology.getQuery() + "%"));
                or.add(cb.like(root.get("productName"), "%" + technology.getQuery() + "%"));
                Predicate[] pre_or = new Predicate[or.size()];
                Predicate ora = cb.or(or.toArray(pre_or));
                return query.where(Pre_And, Pre_Or, ora).getRestriction();
            }
        }, pageable);
    }

    public void save(Technology technology, List<MultipartFile> files) throws Exception {
        fileRestService.upload(null, technology, files);
        saveTech(technology);
    }

    public void save2(Technology technology) throws Exception {
        saveTech(technology);
    }

    @Transactional
    public void saveTech(Technology technology) throws Exception {
        technologyDao.save(technology);
        if (!StringUtils.isEmpty(technology.getTechnologiesList())) {
            List<Technology> technologies = JSONArray.parseArray(technology.getTechnologiesList(), Technology.class);
            for (Technology techno : technologies) {
                techno.setpId(technology.getId());
                techno.setCompanyId(technology.getCompanyId());
                technologyDao.save(techno);
            }
        }
    }



    @Transactional
    public void update(Technology technology, List<MultipartFile> files) throws Exception {
        fileRestService.upload(technologyDao.findById(technology.getId()), technology, files);
        updateTech(technology);
    }


    @Transactional
    public void update2(Technology technology) throws Exception {
        updateTech(technology);
    }



    public void updateTech(Technology technology) throws Exception {
        technologyDao.save(technology);
        if (!StringUtils.isEmpty(technology.getTechnologiesList())) {
            deletes(technology.getId());
            List<Technology> technologies = JSONArray.parseArray(technology.getTechnologiesList(), Technology.class);
            for (Technology techno : technologies) {
                techno.setpId(technology.getId());
                techno.setCompanyId(technology.getCompanyId());
                technologyDao.save(techno);
            }
        }
    }

    public List<Technology> findByProductName(String name) {
        return technologyDao.findByProductName(name);
    }

    public Technology findById(String id) {
        Technology technology = technologyDao.findById(id);
        List<Technology> childs = technologyDao.findByPId(technology.getId());
        technology.setTechnologies(childs);
        return technology;
    }

    @Transactional
    public void delete(String id) {
        Technology technology = technologyDao.findById(id);
        technologyDao.delete(technology);
        deletes(id);
    }

    private void deletes(String pId) {
        List<Technology> technologies = technologyDao.findByPId(pId);
        if (technologies.size() > 0) {
            technologyDao.deleteAll(technologies);
        }
    }

    public List<Technology> findAll(String companyId) {
        if (!StringUtils.isEmpty(companyId)) {
            return technologyDao.findByCompanyId(companyId);
        }
        return technologyDao.findAll();
    }

}
